package org.platform.processor.monitor.job;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.mc.mic.core.log.bus.BusLogPusher;
import com.mc.mic.core.log.frame.LogBo;
import lombok.extern.slf4j.Slf4j;
import org.platform.constant.LogType;
import org.platform.core.JobManager;
import org.platform.mo.bussmo.diagnose.event.AlarmBO;
import org.platform.mo.bussmo.diagnose.event.Event;
import org.platform.mo.bussmo.diagnose.event.EventBO;
import org.platform.mo.bussmo.diagnose.event.StandardEventBO;
import org.platform.mo.bussmo.log.AlarmMqBO;
import org.platform.processor.monitor.data.CacheLibraryPO;
import org.platform.tool.util.JsonUtils;
import org.platform.tool.util.TimeUtils;
import org.quartz.*;
import org.quartz.impl.JobDetailImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 本线程主要是将报警的设备信息通过MQ推动到  [客服端]  和  [信息中心]
 *
 * @author FengJie
 * @date 2018/5/24
 */
@Service
@Slf4j
public class PromoteAlarmDeviceJob implements InterruptableJob {
    private static final String TOPIC = "ParamAlarm";
    private Map<String, AlarmBO> alarmDeviceMap = CacheLibraryPO.getCacheLibraryPO().getAlarmDeviceMap();

    @Autowired
    private BusLogPusher mqLog;
    @Autowired
    private JobManager job;

    /**
     * 初始化消息队列和定时器机制
     */
    @PostConstruct
    void init() {
        JobDetailImpl jd = new JobDetailImpl();
        jd.setJobClass(PromoteAlarmDeviceJob.class);
        jd.setKey(JobKey.jobKey("PromoteAlarmDeviceJob"));
        SimpleTrigger trigger = TriggerBuilder.newTrigger()
                .withSchedule(SimpleScheduleBuilder
                        .simpleSchedule()
                        .withIntervalInSeconds(3)
                        .repeatForever())
                .startNow()
                .build();
        job.register(jd, trigger);
    }

    @Override
    public void interrupt() {
    }

    @Override
    public void execute(JobExecutionContext context) {
        try {
            if (!alarmDeviceMap.isEmpty()) {
                List<AlarmBO> alarmList = new ArrayList<>(alarmDeviceMap.size());
                alarmDeviceMap.forEach((k, v) -> alarmList.add(v));
                mqLog.log(new LogBo<>(LogType.DEVICE_ALARM_LOG, new AlarmMqBO(alarmList)));
                mqLog.log(getAlarmInfo(), TOPIC);
            }
        } catch (JsonProcessingException e) {
            log.error("报警设备推送异常,错误信息:", e);
        }
    }


    /**
     * 获取告警信息
     *
     * @return json 类型的告警信息
     */
    private String getAlarmInfo() throws JsonProcessingException {
        EventBO eventBO = new EventBO();
        List<Event> eventList = new ArrayList<>();
        alarmDeviceMap.forEach((k, v) -> {
            eventList.add(conversion((v)));
        });
        eventBO.setEventList(eventList);
        return JsonUtils.beanToJson(eventBO, true);
    }


    /**
     * 获取单个告警信息
     *
     * @param alarmBO 最终告警库
     * @return 接口文档所需数据
     */
    private Event conversion(AlarmBO alarmBO) {
        Map<String, List<StandardEventBO>> standardEventBOMap = CacheLibraryPO.getCacheLibraryPO().getStandardReferenceSourceMap();
        List<StandardEventBO> standardEventBOList = standardEventBOMap.get(alarmBO.getDeviceid() + "_" + alarmBO.getDevattr());

        Event event = new Event();
        event.setId(alarmBO.getId());
        event.setKnowledgeID(String.valueOf(alarmBO.getKnowledgeid()));
        event.setHappendTime(TimeUtils.timestampsToStr(alarmBO.getHappendtime()));
        event.setDeviceID(alarmBO.getDeviceid());
        event.setDevAttr(alarmBO.getDevattr());
        event.setDevAttrVal(alarmBO.getDevattrval());
        event.setIsConfirmed(String.valueOf(alarmBO.getIsconfirmed()));
        event.setIsRestored(String.valueOf(alarmBO.getIsrestored()));
        event.setRestoreTime(TimeUtils.timestampsToStr(alarmBO.getRestoretime()));
        event.setNote(alarmBO.getNote());

        StandardEventBO standardEventBO = null;
        for (StandardEventBO bo : standardEventBOList) {
            if (alarmBO.getId().equals(bo.getId())) {
                standardEventBO = bo;
                break;
            }
        }
        if (standardEventBO != null) {
            event.setStation(standardEventBO.getStation());
            event.setSystem(standardEventBO.getSystem());
            event.setDeviceType(standardEventBO.getDevicetype());
            event.setModule(standardEventBO.getModule());
            event.setUnit(standardEventBO.getUnit());
            event.setLevel(String.valueOf(standardEventBO.getLevel()));
            event.setAffectLevel(String.valueOf(standardEventBO.getAffectlevel()));
            event.setAffectDesc(standardEventBO.getAffectdesc());
            event.setAlarmReason(standardEventBO.getAlarmreason());
            event.setAdvise(standardEventBO.getAdvise());
            event.setReportTime(TimeUtils.timestampsToStr(standardEventBO.getReporttime()));
            event.setReportCount(String.valueOf(standardEventBO.getReportcount()));
            event.setAttrID(standardEventBO.getAttrid());
            event.setAttrType(String.valueOf(standardEventBO.getAttrtype()));
            event.setEnumVal(standardEventBO.getEnumval());
            event.setMaxVal(String.valueOf(standardEventBO.getMaxval()));
            event.setMinVal(String.valueOf(standardEventBO.getMinval()));
            event.setAlarmType(String.valueOf(standardEventBO.getAlarmtype()));
        }
        return event;
    }
}
